gusucode.com > VC++ 界面很酷的一款多媒体播放器 > VC++ 界面很酷的一款多媒体播放器/gusucode/xMedia代码注释中/videownd.cpp
//Download by http://www.NewXing.com /**************************************** * File: Videownd.cpp * * Last modified: 2004.2.15 * * Author: Yuanyi-Zhang * * Version: 0.0.1.0 * * CopyLeft 2004 xMedia team * ****************************************/ /**************************************************************** * * * This file may be distributed and/or modified under the terms * * of the GNU General Public License version 2 as published by * * the Free Software Foundation and appearing in the file * * LICENSE.GPL included in the packaging of this file. * * * ****************************************************************/ #pragma warning(disable:4786) #include <tchar.h> #include <windows.h> #include <commctrl.h> #include <assert.h> #include "util.h" #include "messagedef.h" #include "Videowindow.h" ////////////////////////////////// VideoWnd::VideoWnd(): m_hWnd( NULL ), m_ErrorString( _T("") ), m_HasCreated(false), m_ClassName( _T("VideoWnd") ), m_lpIL(0), m_LButtonDown(false), m_Show(false) { m_hDCBack = NULL; m_hBmpBack = NULL; m_hMainBmp = NULL; m_hMaskBmp = NULL; m_hElemBmp = NULL; m_PlayProg = -1; } /////////////////////////////////// //注册窗口类 BOOL VideoWnd::RegisterClass( HINSTANCE hInstance ) { WNDCLASSEX wndclass; ZeroMemory(&wndclass, sizeof(wndclass)); //Window class for the main application parent window wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = 0; wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); wndclass.lpszMenuName = 0; wndclass.lpszClassName = m_ClassName.c_str(); wndclass.hIconSm = 0; return RegisterClassEx(&wndclass); } ////////////////////////////////// //创建视频窗口 bool VideoWnd::Create( HINSTANCE hInstance, HWND Parent) { if( m_HasCreated ) { m_ErrorString=_T("错误,重复创建主窗口!"); return false; } if( !RegisterClass( hInstance ) ) { m_ErrorString=_T("注册窗口类失败!"); return false; } MDICREATESTRUCT mdic; memset(& mdic, 0, sizeof(mdic)); mdic.lParam = (LPARAM) this; HWND hWnd=CreateWindowEx( WS_EX_TOOLWINDOW, m_ClassName.c_str(), NULL, WS_POPUP, 0, 0, 100, 100, Parent, 0, hInstance, &mdic ); if(hWnd==NULL) { m_ErrorString = _T( "创建视频窗口失败,不明错误!" ); return false; } if( !InitTooltips( hWnd, hInstance ) ) { return false; } m_ErrorString = _T( "" ); return true; } ///////////////////////////////////// //读取皮肤配置 bool VideoWnd::LoadSkinConfig() { if( m_lpIL == NULL ) { m_ErrorString = _T("未设置配置文件"); return false; } string strWndRect; strWndRect = m_lpIL->Get( _T( "vwwindowrect" ) ); if( strWndRect.compare( _T( "" ) ) == 0 ) { m_ErrorString = _T("配置文件不完整,无法读取所需信息!"); return false; } m_WndRect = StringToRect( strWndRect ); strWndRect = m_lpIL->Get( _T( "vwvideowndrect" ) ); if( strWndRect.compare( _T( "" ) ) == 0 ) { m_ErrorString = _T("配置文件不完整,无法读取所需信息!"); return false; } m_VideoRect = StringToRect( strWndRect ); m_SkinName = m_lpIL->Get( _T( "skinname" ) ); m_vecElement.push_back( Element( _T("vwfbbutton"), m_lpIL, XM_VWFBBUTTON, true ) ); m_vecElement.push_back( Element( _T("vwffbutton"), m_lpIL, XM_VWFFBUTTON, true ) ); m_vecElement.push_back( Element( _T("vwstopbutton"), m_lpIL, XM_VWSTOPBUTTON, true ) ); m_vecElement.push_back( Element( _T("vwplaybutton"), m_lpIL, XM_VWPLAYBUTTON, true ) ); m_vecElement.push_back( Element( _T("vwpausebutton"), m_lpIL, XM_VWPAUSEBUTTON, true ) ); m_vecElement.push_back( Element( _T("vwprogslider"), m_lpIL, XM_VWPROGSLIDER, true ) ); m_vecElement.push_back( Element( _T("vwprogbar"), m_lpIL, XM_VWPROGBAR, true ) ); return true; } ////////////////////////////////////// //将窗口消息发送到视频窗口俄消息处理函数 LRESULT CALLBACK VideoWnd::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { VideoWnd *pMainWnd; if ( uMsg==WM_NCCREATE ) { assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) ); MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams; if( pMDIC ) pMainWnd = ( VideoWnd *) (pMDIC->lParam); else return 0; assert( ! IsBadReadPtr(pMainWnd, sizeof( VideoWnd ) ) ); SetWindowLong(hWnd, GWL_USERDATA, (LONG) pMainWnd); } else pMainWnd=( VideoWnd *)GetWindowLong(hWnd, GWL_USERDATA); return pMainWnd->MsgProc( hWnd, uMsg, wParam, lParam ); } ////////////////////////////////////////// //消息处理函数 long VideoWnd::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { POINT p; switch( uMsg ) { case WM_CREATE: m_hWnd = hWnd; if( !initials( hWnd ) ) { MessageBox( hWnd, GetErrorString().c_str(), "错误", MB_OK|MB_ICONWARNING ); } break; case WM_PAINT: onDraw(); break; case WM_LBUTTONDOWN: SetCapture( hWnd ); p.x = LOWORD(lParam); p.y = HIWORD(lParam); ClientToScreen( hWnd, &p ); onLButtonDown( p ); break; case WM_MOUSEMOVE: GetCursorPos( &p ); onMouseMove( p ); break; case WM_LBUTTONUP: ReleaseCapture(); p.x = LOWORD(lParam); p.y = HIWORD(lParam); ClientToScreen( hWnd, &p ); onLButtonUp( p ); break; case XM_VWPROGBAR: switch( wParam ) { case ELEM_MOUSEMOVE: adjustProg(); break; case ELEM_LBUTTONUP: PostThreadMessage( GetCurrentThreadId(), MC_SEEKING, 0l, 0l ); break; } break; } return DefWindowProc( hWnd, uMsg, wParam, lParam ); } ////////////////////////////////////// //初始化视频窗口 bool VideoWnd::initials( HWND hwnd ) { if( !InitDC() ) { m_ErrorString = _T("初始化DC失败!"); return false; } SetWindowSize(); if( !LoadResource() ) { return false; } // SetWindowRegion(); m_HasCreated = true; return true; } ////////////////////////// //初始化DC bool VideoWnd::InitDC() { if( m_hDCBack ) { DeleteObject( m_hDCBack ); } if( m_hBmpBack ) { DeleteObject( m_hBmpBack ); } HDC hdc; hdc = GetDC( m_hWnd ); m_hDCBack = CreateCompatibleDC( hdc ); m_hBmpBack = CreateCompatibleBitmap( hdc, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top); if( !m_hDCBack || !m_hBmpBack ) { return false; } SelectObject( m_hDCBack, m_hBmpBack ); return true; } /////////////////////// //释放资源 void VideoWnd::ReleaseResource() { if( m_hDCBack ) { DeleteObject( m_hDCBack ); } if( m_hBmpBack ) { DeleteObject( m_hBmpBack ); } if( m_hMaskBmp ) { DeleteObject( m_hMaskBmp ); } if( m_hMainBmp ) { DeleteObject( m_hMainBmp ); } if( m_hElemBmp ) { DeleteObject( m_hElemBmp ); } } //////////////////// //处理OnDraw消息 bool VideoWnd::onDraw( ) { HDC hdc,hdcImg; PAINTSTRUCT ps; hdc = BeginPaint( m_hWnd, &ps ); hdcImg = CreateCompatibleDC( hdc ); SelectObject( hdcImg, m_hMainBmp ); BitBlt( m_hDCBack, 0, 0, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top, hdcImg, 0, 0, SRCCOPY ); vector<Element>::iterator ite; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( !ite->onDraw( m_hDCBack, m_hElemBmp ) ) { return false; } } BitBlt( hdc, 0, 0, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top, m_hDCBack, 0, 0, SRCCOPY ); EndPaint( m_hWnd, &ps ); DeleteObject( hdcImg ); DeleteObject( hdc ); return true; } //////////////////// //读取资源 bool VideoWnd::LoadResource() { if( m_hMaskBmp ) { DeleteObject( m_hMaskBmp ); } if( m_hMainBmp ) { DeleteObject( m_hMainBmp ); } if( m_hElemBmp ) { DeleteObject( m_hElemBmp ); } string maskBmp,mainBmp,elemBmp; maskBmp = _T( "skin\\" ) + m_SkinName + _T( "\\vwmask.bmp" ); mainBmp = _T( "skin\\" ) + m_SkinName + _T( "\\vwmain.bmp" ); elemBmp = _T( "skin\\" ) + m_SkinName + _T( "\\vwelement.bmp" ); m_hMaskBmp = (HBITMAP)LoadImage( NULL, maskBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION ); if( !m_hMaskBmp ) { m_ErrorString = _T("无法读取文件:") + maskBmp; return false; } m_hMainBmp = (HBITMAP)LoadImage( NULL, mainBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION ); if( !m_hMainBmp ) { m_ErrorString = _T("无法读取文件:") + mainBmp; return false; } m_hElemBmp = (HBITMAP)LoadImage( NULL, elemBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION ); if( !m_hElemBmp ) { m_ErrorString = _T("无法读取文件:") + elemBmp; return false; } return true; } //////////////////////////// //初始化工具提示 bool VideoWnd::InitTooltips( HWND hwnd, HINSTANCE hInst ) { HWND hwndTT; //Tooltip控件句柄 //创建Tooltip控件 hwndTT = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, NULL, hInst, NULL ); if( hwndTT == NULL ) { m_ErrorString = _T("创建工具提示窗口失败!"); return false; } SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); //这个结构体存储Tooltip控件的相关信息 TOOLINFO ti; unsigned int uid = 0; //初始化ti结构体成员 ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_SUBCLASS; ti.hwnd = hwnd; ti.hinst = hInst; ti.uId = uid; TCHAR tcsTooltip[256]; vector<Element>::iterator ite; RECT rect; string str; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { rect = ite->getRectPos(); str = ite->getTooltip(); if( (rect.left == rect.right && rect.top == rect.bottom) || str.compare( _T("") ) == 0 ) { continue; } strcpy( tcsTooltip, str.c_str() ); ti.lpszText = tcsTooltip; ti.rect = rect; //添加工具提示 SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); } return true; } //////////////////////////// //设置窗口可见区域 void VideoWnd::SetWindowRegion() { HRGN hWndRgn; RECT clientRect,wndRect; GetClientRect( m_hWnd, &clientRect ); GetWindowRect( m_hWnd, &wndRect ); POINT start = { 0, 0 }; ClientToScreen( m_hWnd, &start ); hWndRgn = CreateRectRgn( start.x - wndRect.left, start.y - wndRect.top, clientRect.right - clientRect.left + start.x - wndRect.left, clientRect.bottom - clientRect.top + start.y - wndRect.top ); BITMAP bmp; GetObject(m_hMaskBmp, sizeof(bmp), &bmp); HRGN temp; HDC hdc = GetDC( m_hWnd ); HDC hdcImg = CreateCompatibleDC( hdc ); ReleaseDC( m_hWnd, hdc ); SelectObject( m_hDCBack, m_hBmpBack ); SelectObject( hdcImg, m_hMaskBmp ); BitBlt( m_hDCBack, 0, 0, m_WndRect.right - m_WndRect.left, m_WndRect.bottom - m_WndRect.top, hdcImg, 0, 0, SRCCOPY ); DeleteObject( hdcImg ); for( int i = 0; i < bmp.bmWidth; i++ ) { for( int j = 0; j < bmp.bmHeight; j++ ) { if( GetPixel( m_hDCBack, i, j ) == RGB( 255, 255, 255 ) ) { temp = CreateRectRgn( start.x - wndRect.left + i, start.y - wndRect.top + j, start.x - wndRect.left + i + 1, start.y - wndRect.top + j + 1 ); CombineRgn( hWndRgn, hWndRgn, temp, RGN_XOR ); DeleteObject( temp ); } } } SetWindowRgn( m_hWnd, hWndRgn, false ); } //////////////////////////// //处理鼠标左键按下消息 void VideoWnd::onLButtonDown( POINT p ) { m_LButtonDown = true; m_clickPos = p; bool isElemClicked = false; ScreenToClient( m_hWnd, &p ); vector<Element>::iterator ite; RECT validRect; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( ite->onLButtonDown( p ) ) { isElemClicked = true; validRect = ite->getRectPos(); InvalidateRect( m_hWnd, &validRect, false ); } } if( isElemClicked ) { m_LButtonDown = false; } } ////////////////////////// //处理鼠标移动消息 void VideoWnd::onMouseMove( POINT p ) { RECT wndRect; GetWindowRect( m_hWnd, &wndRect ); if( m_LButtonDown ) { wndRect.left += p.x - m_clickPos.x; wndRect.right += p.x - m_clickPos.x; wndRect.bottom += p.y - m_clickPos.y; wndRect.top += p.y - m_clickPos.y; m_clickPos = p; MoveWindow(m_hWnd, wndRect.left, wndRect.top, wndRect.right - wndRect.left, wndRect.bottom - wndRect.top, true ); } else { ScreenToClient( m_hWnd, &p ); vector<Element>::iterator ite; RECT validRect; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( ite->onMouseMove( p ) ) { validRect = ite->getRectPos(); InvalidateRect( m_hWnd, &validRect, false ); } } } } ///////////////////////// //处理鼠标左键松开消息 void VideoWnd::onLButtonUp( POINT p ) { if( m_LButtonDown ) { m_LButtonDown = false; } else { ScreenToClient( m_hWnd, &p ); vector<Element>::iterator ite; RECT validRect; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( ite->onLButtonUp( p ) ) { validRect = ite->getRectPos(); InvalidateRect( m_hWnd, &validRect, false ); } } } } ////////////////////////////////// //通过按钮名称获取按钮 Element* VideoWnd::getElementByName( string str ) { vector<Element>::iterator ite; for( ite = m_vecElement.begin(); ite != m_vecElement.end(); ite++ ) { if( str.compare( ite->getName() ) == 0 ) break; } if( ite == m_vecElement.end() ) { return NULL; } return ite; } //////////////////////////////////// //调整播放进度 void VideoWnd::adjustProg() { Element* progressBar = getElementByName( _T("vwprogbar") ); Element* progressSlider = getElementByName( _T("vwprogslider") ); RECT validRect = progressSlider->getRectPos(); m_PlayProg = adjustSlider( progressSlider, progressBar ); InvalidateRect( m_hWnd, &validRect, false ); } //////////////////////////////////// //设置播放进度 void VideoWnd::setPlayProg( int prog ) { Element* progressBar = getElementByName( _T("vwprogbar") ); Element* progressSlider = getElementByName( _T("vwprogslider") ); RECT validRect = progressSlider->getRectPos(); adjustSlider( progressSlider, progressBar, prog ); InvalidateRect( m_hWnd, &validRect, false ); }